// crc16
package crc16

//计算dat数组中字节的CRC16值，多项式 0xA001
func Crc16_A001(dat []byte) (crc16 uint16, hi byte, lo byte) {
	var crc_reg, crc_gen uint16 = 0xFFFF, 0xA001

	for i, l := 0, len(dat); i < l; i++ {
		crc_reg = (uint16(dat[i]) & 0xff) ^ crc_reg
		for j := 8; j > 0; j-- {
			if crc_reg&0x01 == 1 {
				crc_reg >>= 1
				crc_reg ^= crc_gen
			} else {
				crc_reg >>= 1
			}
		}
	}

	hi, lo = byte(crc_reg>>8), byte(crc_reg)

	return crc_reg, hi, lo
}

//为buf计算crc16校验码，并填充到末尾:低位，高位。
//buf缓冲器不含CRC16数据
func Crc16_A001_Padding(buf []byte) []byte {
	_, hi, lo := Crc16_A001(buf)
	buf = append(buf, lo, hi)
	return buf
}

//buf中包含数据及CRC16校验码，更新校验码
func Crc16_A001_Update(buf []byte) {
	l := len(buf)
	_, hi, lo := Crc16_A001(buf[:l-2])
	buf[l-2], buf[l-1] = lo, hi
}

//校验CRC16
//buf <数据...><CRC16_低位字节><CRC16_高位字节>
func Crc16_A001_Check(buf []byte) (match bool, hi, lo byte) {
	l := len(buf)
	_, hi, lo = Crc16_A001(buf[:l-2])
	m := hi == buf[l-1] && lo == buf[l-2]
	return m, hi, lo
}
